﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AnaxibiaStudios.Smug
{
  public class SmugException : Exception
  {
    public Type TargetType { get; set; }

    public SmugException(Type targetType) : this(targetType, "Smug failure") { }
    public SmugException(Type targetType, string message)
      : base(string.Format("[{0}] {1}", targetType, message))
    {
      TargetType = targetType;
    }
  }

  public class SmugConstructorNotFoundException : SmugException
  {
    public SmugConstructorNotFoundException(Type targetType)
      : base(targetType, "No matching constructor found for proxy")
    {
    }
  }

  public class SmugCannotProxyNonPublicTypesException : SmugException
  {
    public SmugCannotProxyNonPublicTypesException(Type targetType)
      : base(targetType, "Smug cannot build proxies of non public or internal types")
    {
    }
  }

  public class SmugCannotProxySealedTypesException : SmugException
  {
    public SmugCannotProxySealedTypesException(Type targetType)
      : base(targetType, "Smug cannot build proxies of static types")
    {
    }
  }

  public class SmugNoConstructorsException : SmugException
  {
    public SmugNoConstructorsException(Type targetType)
      : base(targetType, "Smug cannot build proxies of types with private or internal constructors only")
    {
    }
  }

  public class SmugIndexerConflictException : SmugException
  {
    public SmugIndexerConflictException(Type targetType)
      : base(targetType, "Smug cannot build proxies of types with conflicting Item and custom named indexer properties")
    {
    }
  }

  public class SmugCompilationException : SmugException
  {
    public string SourceCode { get; set; }

    public SmugCompilationException(Type targetType, string message, string source)
      : base(targetType, message)
    {
      SourceCode = source;
    }
  }

  public class SmugUndefinedGenericArgumentException : SmugException
  {
    public SmugUndefinedGenericArgumentException(Type targetType)
      : base(targetType, "Smug cannot proxy generic types without defining all the generics parameters")
    {
    }
  }

  public class SmugHasAbstractInternalsException : SmugException
  {
    public SmugHasAbstractInternalsException(Type targetType)
      : base(targetType, "Smug cannot proxy types containing internal abstract members")
    {
      //Solution: make them `protected internal` at least...
    }
  }
}
